package com.yeskery.nut.extend.responsive.convert;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yeskery.nut.core.NutException;
import com.yeskery.nut.plugin.PluginBeanMetadata;
import com.yeskery.nut.plugin.PluginBeanMetadataExtender;

import java.lang.reflect.Type;
import java.util.Collection;
import java.util.Collections;

/**
 * 基于Jackson的json转换器
 * @author sprout
 * 2022-06-16 10:22
 */
public class JacksonJsonResponsiveConvert extends CustomResponsiveConvert implements PluginBeanMetadataExtender {

    /** ObjectMapper对象 */
    private final ObjectMapper objectMapper;

    /**
     * 构建基于Jackson的转换器
     */
    public JacksonJsonResponsiveConvert() {
        this.objectMapper = new ObjectMapper();
    }

    /**
     * 构建基于Jackson的转换器
     * @param objectMapper ObjectMapper对象
     */
    public JacksonJsonResponsiveConvert(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    @Override
    public String doConvertTo(Object data) {
        try {
            return objectMapper.writeValueAsString(data);
        } catch (JsonProcessingException e) {
            throw new NutException("Serialization Failure.", e);
        }
    }

    @Override
    public Object doConvertFrom(String data) {
        try {
            return objectMapper.readValue(data, Object.class);
        } catch (JsonProcessingException e) {
            throw new NutException("Serialization Failure.", e);
        }
    }

    @Override
    public <T> T doConvertFromString(String data, Class<T> clazz) {
        try {
            return objectMapper.readValue(data, clazz);
        } catch (JsonProcessingException e) {
            throw new NutException("Serialization Failure.", e);
        }
    }

    @Override
    public <T> T convertFromStringByType(String data, Type type) {
        try {
            return objectMapper.readValue(data, new TypeReference<T>() {
                @Override
                public Type getType() {
                    return type;
                }
            });
        } catch (JsonProcessingException e) {
            throw new NutException("Serialization Failure.", e);
        }
    }

    @Override
    public Collection<PluginBeanMetadata> getExtendPluginBeanMetadata() {
        return Collections.singleton(new PluginBeanMetadata("objectMapper", objectMapper, ObjectMapper.class));
    }
}
